wudysoft commited on
Commit
13e582b
·
verified ·
1 Parent(s): 8c7d831

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +720 -391
app.js CHANGED
@@ -13,196 +13,746 @@ const config = {
13
  userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
14
  };
15
 
16
- let browser, page;
 
 
17
 
18
- const utils = {
19
- async initialize() {
20
- if (!browser) {
21
- browser = await chromium.launch({ headless: true });
22
- const context = await browser.newContext({
23
- viewport: config.viewport,
24
- userAgent: config.userAgent
25
- });
26
 
27
- await context.route('**/*', (route) => {
28
- const url = route.request().url();
29
- if (url.endsWith('.png') || url.endsWith('.jpg') || url.includes('google-analytics')) {
30
- return route.abort();
31
- }
32
- route.continue();
33
- });
34
 
35
- page = await context.newPage();
36
- await page.goto('https://www.bratgenerator.com/', { waitUntil: 'domcontentloaded', timeout: 10000 });
 
 
 
 
 
 
 
 
37
 
38
- try {
39
- await page.click('#onetrust-accept-btn-handler', { timeout: 2000 });
40
- } catch { }
 
 
 
41
 
42
- await page.evaluate(() => setupTheme('white'));
43
- }
44
- },
 
 
 
 
 
45
 
46
- async generateBrat(text) {
47
- await page.fill('#textInput', text);
48
- const overlay = page.locator('#textOverlay');
49
- return overlay.screenshot({ timeout: 3000 });
50
- },
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- async close() {
53
- if (browser) await browser.close();
54
- }
55
- };
56
 
57
- const app = express();
58
- app.use(express.json());
59
- app.use(cors());
 
 
 
 
 
 
 
 
 
60
 
61
- app.get('/', (req, res) => {
62
- res.send('<h1>Welcome to the Web Scraping API</h1>');
63
- });
 
 
 
 
 
 
 
 
 
 
64
 
65
- app.get('/brat', async (req, res) => {
66
- try {
67
- const { text: q } = req.query;
68
- if (!q) {
69
- return res.json({
70
- name: 'HD Bart Generator API',
71
- message: 'Parameter text di perlukan',
72
- version: '2.1.0',
73
- runtime: {
74
- os: os.type(),
75
- platform: os.platform(),
76
- architecture: os.arch(),
77
- cpuCount: os.cpus().length,
78
- uptime: `${os.uptime()} seconds`,
79
- memoryUsage: `${Math.round((os.totalmem() - os.freemem()) / 1024 / 1024)} MB used of ${Math.round(os.totalmem() / 1024 / 1024)} MB`
80
- }
81
- });
82
- }
83
- const imageBuffer = await utils.generateBrat(q);
84
- res.set('Content-Type', 'image/png');
85
- res.send(imageBuffer);
86
- } catch (error) {
87
- console.error(error);
88
- res.status(500).json({
89
- status: false,
90
- message: 'Error generating image',
91
- error: process.env.NODE_ENV === 'development' ? error.message : undefined
92
- });
93
- }
94
- });
95
 
96
- app.get('/screenshot', async (req, res) => {
97
- const { url } = req.query;
 
 
 
 
 
 
98
 
99
- if (!url) {
100
- return res.status(400).send('URL is required');
101
- }
 
 
 
 
 
 
 
102
 
103
- try {
104
- const browser = await chromium.launch();
105
- const page = await browser.newPage();
106
- await page.goto(url);
107
-
108
- const screenshotBuffer = await page.screenshot();
109
- await browser.close();
110
-
111
- res.type('image/png').send(screenshotBuffer);
112
- } catch (error) {
113
- res.status(500).send('Internal Server Error');
114
- }
115
- });
116
 
 
 
 
 
 
 
 
 
117
 
118
- function generateRandomString(length) {
119
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
120
- let result = '';
121
- for (let i = 0; i < length; i++) {
122
- result += characters.charAt(Math.floor(Math.random() * characters.length));
123
- }
124
- return result;
125
  }
126
 
127
- class MicrosoftBingAutoLogin {
128
- constructor(bing_account, bing_password) {
129
- console.log('Initializing auto login for Microsoft Bing ...');
130
- this.bing_account = bing_account;
131
- this.bing_password = bing_password;
132
- this.init();
133
- }
 
 
134
 
135
- async init() {
136
- this.browser = await chromium.launch(); // Launch browser with Playwright
137
- }
 
 
138
 
139
- /** Login to Microsoft Bing */
140
- async login() {
141
- const sig = generateRandomString(32);
142
- const CSRFToken = generateRandomString(8) + '-' + generateRandomString(4) + '-' + generateRandomString(4) + '-' + generateRandomString(4) + '-' + generateRandomString(12);
143
- const loginUrl = `https://login.live.com/login.srf?wa=wsignin1.0&rpsnv=13&id=264960&wreply=https%3a%2f%2fwww.bing.com%2fsecure%2fPassport.aspx%3fedge_suppress_profile_switch%3d1%26requrl%3dhttps%253a%252f%252fwww.bing.com%252fsearch%253ftoWww%253d1%2526redig%253d9220EACAFFCA40508E4E7BD52023921B%2526q%253dBing%252bAI%2526showconv%253d1%2526wlexpsignin%253d1%26sig=${sig}&wp=MBI_SSL&lc=1028&CSRFToken=${CSRFToken}&aadredir=1`;
 
144
 
145
- // Open Microsoft Bing login page
146
- const page = await this.browser.newPage();
147
- await page.goto(loginUrl);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
- // Enter the Bing account and password
150
- const accountInput = await page.$('input[name="loginfmt"]');
151
- await accountInput.type(this.bing_account);
152
- const passwordInput = await page.$('input[name="passwd"]');
153
- await passwordInput.type(this.bing_password);
154
 
155
- // Submit login form
156
- const submitButton = await page.$('input[type="submit"]');
157
- await submitButton.click();
 
 
 
 
 
 
158
 
159
- // Wait for login to complete (you can adjust the wait time or use a more sophisticated wait)
160
- await page.waitForNavigation();
161
- }
 
 
 
 
 
 
 
162
 
163
- async getCookies() {
164
- const page = await this.browser.newPage();
165
- await page.goto('https://bing.com/chat'); // Navigate to Bing Chat to get the cookies
166
- const cookies = await page.cookies();
167
- return cookies;
168
- }
169
  }
170
 
171
- // Create the API route for login
172
- app.get('/login', async (req, res) => {
173
- const { user, pass } = req.query;
174
 
175
- if (!user || !pass) {
176
- return res.status(400).send('Missing username or password.');
177
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
 
179
  try {
180
- const bingLogin = new MicrosoftBingAutoLogin(user, pass);
181
- await bingLogin.login(); // Perform login
182
- const cookies = await bingLogin.getCookies(); // Get cookies after login
183
- res.json(cookies); // Send cookies as response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  } catch (error) {
185
- res.status(500).send('Error during login: ' + error.message);
 
186
  }
187
  });
188
 
189
- app.get('/cookie', async (req, res) => {
190
- const { url } = req.query;
191
 
192
- if (!url) {
193
- return res.status(400).send('URL is required');
194
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
196
- try {
197
- const browser = await chromium.launch();
198
- const page = await browser.newPage();
199
- await page.goto(url);
200
- const cookies = await page.context().cookies();
201
- await browser.close();
202
- res.json(cookies);
203
- } catch (error) {
204
- res.status(500).send('Internal Server Error');
205
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  });
207
 
208
  app.get('/welcome', async (req, res) => {
@@ -587,8 +1137,21 @@ close_btn.addEventListener('click', () => {
587
  </html>`;
588
 
589
  try {
590
- const browser = await chromium.launch(); // Launch Playwright Chromium browser
591
- const page = await browser.newPage();
 
 
 
 
 
 
 
 
 
 
 
 
 
592
  await page.setContent(html);
593
  const buffer = await page.screenshot({ type: 'png' });
594
  await browser.close();
@@ -601,247 +1164,13 @@ close_btn.addEventListener('click', () => {
601
  }
602
  });
603
 
604
- app.get('/youtube-videos', async (req, res) => {
605
- const channelName = req.query.name || 'YasoobKhalid'; // Default to 'YasoobKhalid' if no name is provided
606
- const url = `https://www.youtube.com/@${channelName}/videos`;
607
-
608
- const browser = await chromium.launch({ headless: true });
609
- const page = await browser.newPage();
610
- await page.goto(url);
611
-
612
- const channelTitle = "Title" || await page.locator('yt-formatted-string[class*="ytd-channel-name"]').textContent();
613
- const handle = await page.locator('yt-formatted-string#channel-handle').textContent();
614
- const subscriberCount = await page.locator('yt-formatted-string#subscriber-count').textContent();
615
-
616
- let lastHeight = await page.evaluate(() => {
617
- return document.documentElement.scrollHeight;
618
- });
619
-
620
- const WAIT_IN_SECONDS = 5;
621
- while (true) {
622
- await page.evaluate('window.scrollTo(0, document.documentElement.scrollHeight)');
623
- await page.waitForTimeout(WAIT_IN_SECONDS * 1000); // convert seconds to milliseconds
624
-
625
- const newHeight = await page.evaluate(() => {
626
- return document.documentElement.scrollHeight;
627
- });
628
-
629
- if (newHeight === lastHeight) {
630
- break;
631
- }
632
-
633
- lastHeight = newHeight;
634
- }
635
-
636
- const videoData = await page.evaluate(() => {
637
- const thumbnails = Array.from(document.querySelectorAll('a#thumbnail yt-image img'));
638
- const views = Array.from(document.querySelectorAll('div#metadata-line span:nth-child(1)'));
639
- const titles = Array.from(document.querySelectorAll('#video-title'));
640
- const links = Array.from(document.querySelectorAll('#video-title-link'));
641
-
642
- return titles.map((title, index) => ({
643
- title: title.textContent.trim(),
644
- views: views[index]?.textContent.trim(),
645
- thumbnail: thumbnails[index]?.src,
646
- link: links[index]?.href,
647
- }));
648
- });
649
-
650
- await browser.close();
651
-
652
- res.json({
653
- channelTitle,
654
- handle,
655
- subscriberCount,
656
- videos: videoData,
657
- });
658
- });
659
-
660
- // Define regex patterns
661
- const Patterns = {
662
- channel: {
663
- name: /channelMetadataRenderer\":{\"title\":\"(.*?)\"/,
664
- id: /channelId\":\"(.*?)\"/,
665
- verified: /"label":"Verified"/,
666
- check_live: /{"text":"LIVE"}/,
667
- live: /thumbnailOverlays\":\[(.*?)]/,
668
- video_id: /videoId\":\"(.*?)\"/,
669
- uploads: /gridVideoRenderer\":{\"videoId\":\"(.*?)\"/,
670
- subscribers: /\"subscriberCountText\":{\"accessibility\":(.*?),/,
671
- views: /viewCountText\":{\"simpleText\":\"(.*?)\"}/,
672
- creation: /{\"text\":\"Joined \"},{\"text\":\"(.*?)\"}/,
673
- country: /country\":{\"simpleText\":\"(.*?)\"}/,
674
- custom_url: /canonicalChannelUrl\":\"(.*?)\"/,
675
- description: /{\"description\":{\"simpleText\":\"(.*?)\"}/,
676
- avatar: /height\":88},{\"url\":\"(.*?)\"/,
677
- banner: /width\":1280,\"height\":351},{\"url\":\"(.*?)\"/,
678
- playlists: /{\"url\":\"\/playlist\?list=(.*?)\"/,
679
- video_count: /videoCountText\":{\"runs\":\[{\"text\":(.*?)}\]/,
680
- socials: /q=https%3A%2F%2F(.*?)\"/,
681
- upload_ids: /videoId\":\"(.*?)\"/,
682
- stream_ids: /videoId\":\"(.*?)\"/,
683
- upload_chunk: /gridVideoRenderer\":{(.*?)\"navigationEndpoint/,
684
- upload_chunk_fl_1: /simpleText\":\"Streamed/,
685
- upload_chunk_fl_2: /default_live./,
686
- upcoming_check: /\"title\":\"Upcoming live streams\"/,
687
- upcoming: /gridVideoRenderer\":{\"videoId\":\"(.*?)\"/,
688
- },
689
- video: {
690
- video_id: /videoId\":\"(.*?)\"/,
691
- title: /title\":\"(.*?)\"/,
692
- duration: /approxDurationMs\":\"(.*?)\"/,
693
- upload_date: /uploadDate\":\"(.*?)\"/,
694
- author_id: /channelIds\":\[\"(.*?)\"/,
695
- description: /shortDescription\":\"(.*)\",\"isCrawlable/,
696
- tags: /<meta name=\"keywords\" content=\"(.*?)\">/,
697
- is_streamed: /simpleText\":\"Streamed live/,
698
- is_premiered: /dateText\":{\"simpleText\":\"Premiered/,
699
- views: /videoViewCountRenderer\":{\"viewCount\":{\"simpleText\":\"(.*?)\"/,
700
- likes: /toggledText\":{\"accessibility\":{\"accessibilityData\":{\"label\":\"(.*?) /,
701
- thumbnail: /playerMicroformatRenderer\":{\"thumbnail\":{\"thumbnails\":\[{\"url\":\"(.*?)\"/,
702
- },
703
- playlist: {
704
- name: /{\"title\":\"(.*?)\"/,
705
- video_count: /stats\":\[{\"runs\":\[{\"text\":\"(.*?)\"/,
706
- video_id: /videoId\":\"(.*?)\"/,
707
- thumbnail: /og:image\" content=\"(.*?)\?"/,
708
- },
709
- extra: {
710
- video_id: /videoId\":\"(.*?)\"/,
711
- },
712
- query: {
713
- channel_id: /channelId\":\"(.*?)\"/,
714
- video_id: /videoId\":\"(.*?)\"/,
715
- playlist_id: /playlistId\":\"(.*?)\"/,
716
- },
717
- };
718
-
719
- // Utility function to match patterns
720
- const matchPattern = (pattern, data) => {
721
- const matches = [];
722
- let match;
723
- while ((match = pattern.exec(data)) !== null) {
724
- matches.push(match[1] || match[0]);
725
- }
726
- return matches;
727
- };
728
-
729
- // Fetch YouTube channel data by name
730
- const fetchChannelData = async (channelName) => {
731
- try {
732
- const url = `https://www.youtube.com/@${channelName}/videos`;
733
- const response = await axios.get(url);
734
- return response.data; // return raw HTML content for pattern matching
735
- } catch (error) {
736
- throw new Error('Error fetching YouTube channel data: ' + error.message);
737
- }
738
- };
739
-
740
- // API Endpoint
741
- app.get('/youtube-info', async (req, res) => {
742
- const { name } = req.query; // Get channel name from query parameter
743
-
744
- if (!name) {
745
- return res.status(400).json({ error: 'Channel name is required' });
746
- }
747
-
748
- try {
749
- const data = await fetchChannelData(name); // Fetch the page content from YouTube
750
- const results = {};
751
-
752
- // Apply patterns for channel data extraction
753
- Object.keys(Patterns.channel).forEach((key) => {
754
- const pattern = Patterns.channel[key];
755
- results[key] = matchPattern(pattern, data);
756
- });
757
-
758
- res.json({ channelName: name, data: results });
759
- } catch (error) {
760
- res.status(500).json({ error: error.message });
761
- }
762
- });
763
-
764
- const playwright = {
765
- avLang: ['javascript', 'python', 'java', 'csharp'],
766
-
767
- request: async function(language = 'javascript', code) {
768
- if (!this.avLang.includes(language.toLowerCase())) {
769
- throw new Error(`Language "${language}" is not supported. Choose from available languages: ${this.avLang.join(', ')}`);
770
- }
771
-
772
- const url = 'https://try.playwright.tech/service/control/run';
773
- const headers = {
774
- 'authority': 'try.playwright.tech',
775
- 'accept': '*/*',
776
- 'content-type': 'application/json',
777
- 'origin': 'https://try.playwright.tech',
778
- 'referer': 'https://try.playwright.tech/?l=playwright-test',
779
- 'user-agent': 'Postify/1.0.0',
780
- };
781
-
782
- const data = {
783
- code: code,
784
- language: language
785
- };
786
-
787
- try {
788
- const response = await axios.post(url, data, { headers });
789
- const { success, error, version, duration, output, files } = response.data;
790
- return { success, error, version, duration, output, files };
791
- } catch (error) {
792
- if (error.response) {
793
- const { success, error: errMsg, version, duration, output, files } = error.response.data;
794
- return { success, error: errMsg, version, duration, output, files };
795
- } else {
796
- throw new Error(error.message);
797
- }
798
- }
799
- }
800
- };
801
-
802
- app.get('/view', async (req, res) => {
803
- const { url, count } = req.query;
804
-
805
- if (!url || !count) {
806
- return res.status(400).json({ error: 'Missing required parameters: url and count' });
807
- }
808
-
809
- const language = 'javascript';
810
- const code = `
811
- const { chromium } = require('playwright');
812
- (async () => {
813
- const browser = await chromium.launch({ headless: true });
814
- const page = await browser.newPage();
815
- const targetUrl = '${url}';
816
-
817
- for (let i = 0; i < ${count}; i++) {
818
- await page.goto(targetUrl);
819
- console.log(\`View \${i + 1}: \${targetUrl}\`);
820
- await page.waitForTimeout(3000); // Delay for 3 seconds before next view
821
- }
822
-
823
- await browser.close();
824
- })();
825
- `;
826
-
827
- try {
828
- const data = await playwright.request(language, code);
829
- return res.status(200).json(data);
830
- } catch (error) {
831
- console.error('Error:', error);
832
- return res.status(500).json({ error: error.message });
833
- }
834
- })
835
-
836
 
837
  const PORT = process.env.PORT || 7860;
838
 
839
  app.listen(PORT, async () => {
840
  console.log(`Server running on port ${PORT}`);
841
- await utils.initialize();
842
  });
843
 
844
  process.on('SIGINT', async () => {
845
- await utils.close();
846
  process.exit(0);
847
  });
 
13
  userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
14
  };
15
 
16
+ const app = express();
17
+ app.use(express.json());
18
+ app.use(cors());
19
 
20
+ app.get('/', (req, res) => {
21
+ res.send('<h1>Welcome to the Web Scraping API</h1>');
22
+ });
 
 
 
 
 
23
 
24
+ app.get('/discord', async (req, res) => {
25
+ const { logo, text, text1, text2, text3, text4, text5, text6, text7, text8, text9 } = req.query;
 
 
 
 
 
26
 
27
+ if (!(logo)) {
28
+ return res.status(400).json({ error: 'Missing logo parameters' });
29
+ }
30
+ const html = `<!DOCTYPE html>
31
+ <html lang="en" >
32
+ <head>
33
+ <meta charset="UTF-8">
34
+ <title>Discord Profile Card With Webhook</title>
35
+ <style>
36
+ @import url("https://fonts.googleapis.com/css?family=Roboto:400,400i,700");
37
 
38
+ * {
39
+ margin: 0;
40
+ padding: 0;
41
+ font-family: Roboto, sans-serif;
42
+ box-sizing: border-box;
43
+ }
44
 
45
+ body,
46
+ html {
47
+ height: 100%;
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ background: #0b0b0b;
52
+ }
53
 
54
+ .tooltip {
55
+ display: block;
56
+ position: absolute;
57
+ color: #b6b7b7;
58
+ background: #18191c;
59
+ padding: 0.4rem;
60
+ border-radius: 3px;
61
+ max-width: 150px;
62
+ width: max-content;
63
+ font-size: 0.8rem;
64
+ transform: scale(0);
65
+ transition: 0.055s ease-in-out transform;
66
+ z-index: 10;
67
+ box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.35);
68
+ -webkit-box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.35);
69
+ }
70
 
71
+ .tooltip-up {
72
+ bottom: 30px;
73
+ }
 
74
 
75
+ .tooltip-up::before {
76
+ content: "";
77
+ position: absolute;
78
+ bottom: -5px;
79
+ left: 50%;
80
+ transform: translateX(-50%);
81
+ width: 0;
82
+ height: 0;
83
+ border-left: 6px solid transparent;
84
+ border-right: 6px solid transparent;
85
+ border-top: 6px solid #18191c;
86
+ }
87
 
88
+ .btn {
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+ text-decoration: none;
93
+ background-color: #535353;
94
+ padding: 10px;
95
+ border-radius: 3px;
96
+ color: #fff;
97
+ font-size: 0.85rem;
98
+ transition: 0.2s ease-in-out;
99
+ margin-top: 12px;
100
+ }
101
 
102
+ .btn:hover {
103
+ background-color: #747474;
104
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
+ /* Card */
107
+ .card-container {
108
+ display: flex;
109
+ flex-direction: row;
110
+ justify-content: space-between;
111
+ width: 1450px;
112
+ z-index: 0;
113
+ }
114
 
115
+ .card {
116
+ background: #292b2f;
117
+ width: 345px;
118
+ max-height: 95%;
119
+ height: max-content;
120
+ border-radius: 9px;
121
+ box-shadow: 0px 0px 16px 3px rgba(0, 0, 0, 0.2);
122
+ -webkit-box-shadow: 0px 0px 16px 3px rgba(0, 0, 0, 0.2);
123
+ scrollbar-width: none;
124
+ }
125
 
126
+ .card::-webkit-scrollbar {
127
+ display: none;
128
+ }
129
+
130
+ .card-header .banner {
131
+ width: 100%;
132
+ height: 60px;
133
+ background: #ef5b0d;
134
+ border-radius: 6px 6px 0 0;
135
+ overflow: hidden;
136
+ }
 
 
137
 
138
+ .card-header .banner-img {
139
+ width: 100%;
140
+ height: 120px;
141
+ background-position: center !important;
142
+ background-size: 100% auto !important;
143
+ border-radius: 6px 6px 0 0;
144
+ overflow: hidden;
145
+ }
146
 
147
+ .card-body {
148
+ padding: 15px;
149
+ position: relative;
 
 
 
 
150
  }
151
 
152
+ .card-body .profile-header {
153
+ position: absolute;
154
+ display: flex;
155
+ flex-direction: row;
156
+ align-items: flex-end;
157
+ justify-content: space-between;
158
+ width: calc(100% - 30px);
159
+ top: -50px;
160
+ }
161
 
162
+ .card-body .profile-header .profil-logo {
163
+ position: relative;
164
+ border: 6px solid #292b2f;
165
+ border-radius: 50%;
166
+ }
167
 
168
+ .card-body .profile-header .profil-logo img {
169
+ display: block;
170
+ width: 80px;
171
+ height: 80px;
172
+ border-radius: 50%;
173
+ }
174
 
175
+ .card-body .profile-header .profil-logo::before {
176
+ content: "VIEW PRPFILE";
177
+ position: absolute;
178
+ right: 0;
179
+ top: 0;
180
+ cursor: pointer;
181
+ opacity: 0;
182
+ width: 100%;
183
+ height: 100%;
184
+ color: #eeeeee;
185
+ background: #000000;
186
+ display: flex;
187
+ align-items: center;
188
+ justify-content: center;
189
+ border-radius: 50%;
190
+ font-size: 0.6rem;
191
+ font-weight: 600;
192
+ text-transform: uppercase;
193
+ transition-duration: 0.15s;
194
+ }
195
 
196
+ .card-body .profile-header .profil-logo:hover::before {
197
+ opacity: 1;
198
+ }
 
 
199
 
200
+ .card-body .profile-header .badges-container {
201
+ display: flex;
202
+ flex-wrap: wrap;
203
+ justify-content: flex-end;
204
+ max-width: 220px;
205
+ background: #18191c;
206
+ border-radius: 7px;
207
+ padding: 3px;
208
+ }
209
 
210
+ .card-body .profile-header .badges-container .badge-item {
211
+ position: relative;
212
+ margin: 5px;
213
+ width: 15px;
214
+ height: 15px;
215
+ display: flex;
216
+ justify-content: center;
217
+ align-items: center;
218
+ cursor: pointer;
219
+ }
220
 
221
+ .card-body .profile-header .badges-container .badge-item img {
222
+ height: 110%;
 
 
 
 
223
  }
224
 
225
+ .card-body .profile-header .badges-container .badge-item:hover > .tooltip {
226
+ transform: scale(1);
227
+ }
228
 
229
+ .card-body .profile-body {
230
+ background: #18191c;
231
+ border-radius: 7px;
232
+ padding: 13px;
233
+ margin-top: 40px;
234
+ }
235
+
236
+ .card-body .profile-body .username {
237
+ color: #eeeeee;
238
+ font-weight: 600;
239
+ font-size: 1.3rem;
240
+ display: flex;
241
+ flex-direction: row;
242
+ align-items: center;
243
+ }
244
+
245
+ .card-body .profile-body .username span {
246
+ color: #b9bbbe;
247
+ }
248
+
249
+ .card-body .profile-body .username .badge {
250
+ font-size: 0.65rem;
251
+ background-color: #5865f2;
252
+ text-transform: uppercase;
253
+ font-weight: 300;
254
+ width: max-content;
255
+ padding: 2px 5px;
256
+ margin-left: 5px;
257
+ border-radius: 3px;
258
+ }
259
+
260
+ .card-body .profile-body hr {
261
+ border: none;
262
+ border-top: 0.5px solid #33353b;
263
+ }
264
+
265
+ .card-body .profile-body .category-title {
266
+ color: #d6d6d6;
267
+ font-weight: 700;
268
+ text-transform: uppercase;
269
+ font-size: 0.8rem;
270
+ margin-bottom: 8px;
271
+ }
272
+
273
+ .card-body .profile-body .basic-infos {
274
+ margin-bottom: 14px;
275
+ margin-top: 12px;
276
+ }
277
+
278
+ .card-body .profile-body .basic-infos p {
279
+ color: #bdbebf;
280
+ font-size: 0.9rem;
281
+ }
282
+
283
+ .card-body .profile-body .basic-infos p a {
284
+ color: #02a5e6;
285
+ text-decoration: none;
286
+ }
287
+
288
+ .card-body .profile-body .basic-infos p a:hover {
289
+ text-decoration: underline;
290
+ }
291
+
292
+ .card-body .profile-body .basic-infos p b {
293
+ color: #ddd;
294
+ }
295
+
296
+ .card-body .profile-body .roles {
297
+ margin-bottom: 14px;
298
+ }
299
+
300
+ .card-body .profile-body .roles .roles-list {
301
+ display: flex;
302
+ flex-wrap: wrap;
303
+ }
304
+
305
+ .card-body .profile-body .roles .roles-list .role {
306
+ background: #292b2f;
307
+ color: #c4c4c4;
308
+ border-radius: 3px;
309
+ font-size: 0.75rem;
310
+ font-weight: 300;
311
+ padding: 3px 6px;
312
+ margin-right: 4px;
313
+ margin-top: 4px;
314
+ display: flex;
315
+ align-items: center;
316
+ flex-direction: row;
317
+ }
318
+
319
+ .card-body .profile-body .roles .roles-list .role .role-color {
320
+ position: relative;
321
+ width: 12px;
322
+ height: 12px;
323
+ border-radius: 50%;
324
+ margin-right: 5px;
325
+ }
326
+
327
+ .card-body .profile-body .roles .roles-list .role .role-color:hover::before {
328
+ content: "✕";
329
+ position: relative;
330
+ top: -2px;
331
+ right: 1px;
332
+ font-size: 0.65rem;
333
+ color: #f5f5f5;
334
+ background: rgba(41, 43, 47, 0);
335
+ border-radius: 50%;
336
+ width: 15px;
337
+ height: 15px;
338
+ display: flex;
339
+ align-items: center;
340
+ justify-content: center;
341
+ cursor: pointer;
342
+ }
343
+
344
+ .card-body .profile-body .roles .roles-list .role-add {
345
+ cursor: pointer;
346
+ }
347
+
348
+ .card-body .profile-body .note textarea {
349
+ border: none;
350
+ outline: none;
351
+ background: transparent;
352
+ width: 100%;
353
+ min-height: 30px;
354
+ color: #e0e0e0;
355
+ resize: none;
356
+ font-size: 0.8rem;
357
+ border-radius: 3px;
358
+ padding: 5px;
359
+ box-sizing: border-box;
360
+ scrollbar-width: none;
361
+ }
362
+
363
+ .card-body .profile-body .note textarea::-webkit-scrollbar {
364
+ display: none;
365
+ }
366
+
367
+ .card-body .profile-body .note textarea::placeholder {
368
+ font-size: 0.8rem;
369
+ }
370
+
371
+ .card-body .profile-body .note textarea:focus::placeholder {
372
+ opacity: 0;
373
+ }
374
+
375
+ .card-body .profile-body .message input {
376
+ background: transparent;
377
+ outline: none;
378
+ border: 1.2px solid #272727;
379
+ padding: 13px;
380
+ width: 100%;
381
+ border-radius: 4px;
382
+ color: #eeeeee;
383
+ margin-top: 14px;
384
+ }
385
+ .nitro-card {
386
+ position: relative;
387
+ background-image: linear-gradient(0, #000000, #a77311);
388
+ background-blend-mode: multiply;
389
+ background-color: #0000006c;
390
+ }
391
+
392
+ .nitro-card:before {
393
+ content: "";
394
+ position: absolute;
395
+ top: 0;
396
+ right: 0;
397
+ bottom: 0;
398
+ left: 0;
399
+ z-index: -1;
400
+ margin: -5px;
401
+ border-radius: 12px;
402
+ background: linear-gradient(0, #000000, #e09200);
403
+ }
404
+
405
+ .nitro-card .card-body .profile-body {
406
+ background: linear-gradient(0, #000000, #18191c91);
407
+ }
408
+
409
+ .nitro-card .card-body .profile-header .profil-logo {
410
+ position: relative;
411
+ border-color: transparent;
412
+ z-index: 0;
413
+ }
414
+
415
+ .nitro-card .card-body .profile-header .profil-logo:after {
416
+ content: "";
417
+ position: absolute;
418
+ top: 0;
419
+ right: 0;
420
+ bottom: 0;
421
+ left: 0;
422
+ z-index: -1;
423
+ margin: -6px;
424
+ border-radius: 50%;
425
+ background-color: rgb(74, 50, 7);
426
+ }
427
+
428
+ .nitro-card .card-body .profile-header .badges-container {
429
+ background: #18191c77;
430
+ }
431
+
432
+ .nitro-card .card-body .profile-body .roles .roles-list .role {
433
+ background: #18191c4d;
434
+ border: 1px solid #3f4149;
435
+ }
436
+
437
+ /* Media Queries */
438
+ @media screen and (max-width: 1470px) {
439
+ .card-container {
440
+ width: 1100px;
441
+ }
442
+ .card:last-child {
443
+ display: none;
444
+ }
445
+ }
446
+
447
+ @media screen and (max-width: 1150px) {
448
+ .card-container {
449
+ width: 720px;
450
+ }
451
+ .card:nth-child(3) {
452
+ display: none;
453
+ }
454
+ }
455
+
456
+ @media screen and (max-width: 770px) {
457
+ .card-container {
458
+ width: max-content;
459
+ }
460
+ .card:nth-child(2) {
461
+ display: none;
462
+ }
463
+ }
464
+ </style>
465
+ </head>
466
+ <body>
467
+ <!-- partial:index.partial.html -->
468
+ <div class="card-container">
469
+
470
+ <!-- nitro card -->
471
+
472
+ <div class="card nitro-card">
473
+ <div class="card-header">
474
+ <div
475
+ style="background: url('https://i.ibb.co/wyZxFzw/banner.gif')"
476
+ class="banner-img">
477
+ </div>
478
+ </div>
479
+ <div class="card-body">
480
+ <div class="profile-header">
481
+ <div class="profil-logo">
482
+ <img src=${logo} />
483
+ </div>
484
+ <div class="badges-container">
485
+ <div class="badge-item">
486
+ <img src="https://svgur.com/i/xLC.svg" alt="" />
487
+ <div class="tooltip tooltip-up">${text}</div>
488
+ </div>
489
+ <div class="badge-item">
490
+ <img src="https://svgur.com/i/xN3.svg" alt="" />
491
+ <div class="tooltip tooltip-up">${text1}</div>
492
+ </div>
493
+ <div class="badge-item">
494
+ <img src="https://svgur.com/i/xMp.svg" alt="" />
495
+ <div class="tooltip tooltip-up">${text2}</div>
496
+ </div>
497
+ <div class="badge-item">
498
+ <img src="https://svgur.com/i/xNq.svg" alt="" />
499
+ <div class="tooltip tooltip-up">${text3}</div>
500
+ </div>
501
+ <div class="badge-item">
502
+ <img src="https://svgur.com/i/xNK.svg" alt="" />
503
+ <div class="tooltip tooltip-up">${text4}</div>
504
+ </div>
505
+ <div class="badge-item">
506
+ <img src="https://svgur.com/i/xLD.svg" alt="" />
507
+ <div class="tooltip tooltip-up">${text5}</div>
508
+ </div>
509
+ <div class="badge-item">
510
+ <img src="https://svgur.com/i/xNF.svg" alt="" />
511
+ <div class="tooltip tooltip-up">${text6}</div>
512
+ </div>
513
+ <div class="badge-item">
514
+ <img src="https://svgur.com/i/xNe.svg" alt="" />
515
+ <div class="tooltip tooltip-up">
516
+ ${text7}
517
+ </div>
518
+ </div>
519
+ </div>
520
+ </div>
521
+ <div class="profile-body">
522
+ <div class="username">
523
+ <a> ${text8} </a>
524
+ </div>
525
+ <p style="color: white;">d11b</p>
526
+ <hr/>
527
+ <div class="basic-infos">
528
+ <div class="category-title">${text9}</div>
529
+ <p>
530
+ <b>Discord</b> Verified Account User <br>Joined since &rarr; 2016<br>
531
+ <b>Discord</b> Verified Active Developer<br> since &rarr; Oct 1, 2022
532
+ </p>
533
+ </div>
534
+ <div class="basic-infos">
535
+ <div class="category-title">Member Since</div>
536
+ <div style="display: flex; align-items: center;">
537
+ <img src="https://i.ibb.co/HpbSK8B/icons8-discord-16.png" style="margin-right: 10px;">
538
+ <p style="margin: 0;">Jan 8, 2016</p>
539
+ </div>
540
+ </div>
541
+ <div class="roles">
542
+ <div class="category-title">Roles</div>
543
+ <div class="roles-list">
544
+ <div class="role">
545
+ <div class="role-color" style="background: lightyellow"></div>
546
+ <p>JavaScript</p>
547
+ </div>
548
+ <div class="role">
549
+ <div class="role-color" style="background: darkred"></div>
550
+ <p>HTML</p>
551
+ </div>
552
+ <div class="role">
553
+ <div class="role-color" style="background: darkgreen"></div>
554
+ <p>C++</p>
555
+ </div>
556
+ <div class="role">
557
+ <div class="role-color" style="background: yellow"></div>
558
+ <p>Python</p>
559
+ </div>
560
+ <div class="role">
561
+ <div class="role-color" style="background: darkblue"></div>
562
+ <p>C#</p>
563
+ </div>
564
+ <div class="role">
565
+ <div class="role-color" style="background: orange"></div>
566
+ <p>IT</p>
567
+ </div>
568
+ <div class="role role-add">
569
+ <div class="role-add-text">+</div>
570
+ </div>
571
+ </div>
572
+ </div>
573
+ <div class="note">
574
+ <div class="category-title">Note</div>
575
+ <textarea placeholder="Click to add a note"></textarea>
576
+ </div>
577
+ <div class="message">
578
+ <input id="content" type="text" placeholder=${text9}/>
579
+ </div>
580
+ <div id="message-status" style="display: none;"><b>Message Sent!</b></div>
581
+ </div>
582
+ </div>
583
+ </div>
584
+
585
+ </div>
586
+ <!-- partial -->
587
+ <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js'></script><script src="./script.js"></script>
588
+
589
+ </body>
590
+ </html>
591
+ `;
592
 
593
  try {
594
+ const browser = await chromium.launch({ headless: true }); // Launch Playwright Chromium browser
595
+ const context = await browser.newContext({
596
+ viewport: config.viewport,
597
+ userAgent: config.userAgent
598
+ });
599
+
600
+ await context.route('**/*', (route) => {
601
+ const url = route.request().url();
602
+ if (url.endsWith('.png') || url.endsWith('.jpg') || url.includes('google-analytics')) {
603
+ return route.abort();
604
+ }
605
+ route.continue();
606
+ });
607
+
608
+ const page = await context.newPage();
609
+ await page.setContent(html);
610
+ const buffer = await page.screenshot({ type: 'png' });
611
+ await browser.close();
612
+
613
+ res.set('Content-Type', 'image/png');
614
+ return res.send(buffer);
615
  } catch (error) {
616
+ console.error('Error generating PNG:', error);
617
+ res.status(500).json({ error: 'Failed to convert HTML to PNG' });
618
  }
619
  });
620
 
621
+ app.get('/darkcard', async (req, res) => {
622
+ const { avatar, name, job, button, desc } = req.query;
623
 
624
+ if (!(avatar || name || job || button || desc)) {
625
+ return res.status(400).json({ error: 'Missing avatar, name, job, button, desc parameters' });
626
+ }
627
+ const html = `<!DOCTYPE html>
628
+ <html lang="en" >
629
+ <head>
630
+ <meta charset="UTF-8">
631
+ <title>Glassmorph dark card</title>
632
+ <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css'><style>
633
+ body {
634
+ background-color: #001320;
635
+ background: -webkit-linear-gradient(90deg, 0, #1b121d 50%, #1b121d 100%);
636
+ min-height: 100vh;
637
+ font-size: 1.2rem;
638
+ letter-spacing: 1px;
639
+ }
640
 
641
+ .container {
642
+ min-height: 100vh;
643
+ }
644
+
645
+ .card-container {
646
+ position: relative;
647
+ }
648
+ .card-container::before, .card-container::after {
649
+ width: 200px;
650
+ height: 200px;
651
+ border-radius: 100%;
652
+ position: absolute;
653
+ filter: blur(20px);
654
+ z-index: 0;
655
+ }
656
+ .card-container::before {
657
+ content: "";
658
+ left: -80px;
659
+ top: -80px;
660
+ background: linear-gradient(#1845ad, #23a2f6);
661
+ }
662
+ .card-container::after {
663
+ content: "";
664
+ right: -30px;
665
+ bottom: -80px;
666
+ background: linear-gradient(to right, #ff512f, #f09819);
667
+ }
668
+
669
+ .card {
670
+ backdrop-filter: blur(16px) saturate(180%);
671
+ -webkit-backdrop-filter: blur(16px) saturate(180%);
672
+ background-color: rgba(17, 25, 40, 0.75);
673
+ border-radius: 12px;
674
+ border: 1px solid rgba(255, 255, 255, 0.125);
675
+ text-align: center;
676
+ z-index: 2;
677
+ }
678
+ .card .card-body {
679
+ padding: 1.5rem;
680
+ }
681
+ .card .card-title {
682
+ color: white;
683
+ }
684
+ .card .card-subtitle {
685
+ color: #c0f;
686
+ font-size: 1rem;
687
+ text-transform: uppercase;
688
+ letter-spacing: 2px;
689
+ font-weight: 700;
690
+ opacity: 0.7;
691
+ }
692
+ .card .card-description {
693
+ color: #9ca3af;
694
+ }
695
+ .card .card-img img {
696
+ height: 9rem;
697
+ width: 9rem;
698
+ border: 1px solid rgba(209, 213, 219, 0.3);
699
+ padding: 1rem;
700
+ }
701
+ </style>
702
+ </head>
703
+ <body>
704
+ <!-- partial:index.partial.html -->
705
+ <body>
706
+ <div class="container d-flex flex-column justify-content-center align-items center h-100">
707
+ <div class="row">
708
+ <div class="col-md-4 mx-auto">
709
+ <div class="card-container">
710
+ <div class="card">
711
+ <div class="card-body">
712
+ <div class="card-img mb-4"><img class="rounded-circle" src=${avatar}/></div>
713
+ <h2 class="card-title">${name}</h2>
714
+ <h3 class="card-subtitle">${job}</h3>
715
+ <div class="btn btn-primary mt-4">${button}</div>
716
+ <p class="card-description mb-0 mt-4">${desc}</p>
717
+ </div>
718
+ </div>
719
+ </div>
720
+ </div>
721
+ </div>
722
+ </div>
723
+ </body>
724
+ <!-- partial -->
725
+
726
+ </body>
727
+ </html>
728
+ `;
729
+
730
+ try {
731
+ const browser = await chromium.launch({ headless: true }); // Launch Playwright Chromium browser
732
+ const context = await browser.newContext({
733
+ viewport: config.viewport,
734
+ userAgent: config.userAgent
735
+ });
736
+
737
+ await context.route('**/*', (route) => {
738
+ const url = route.request().url();
739
+ if (url.endsWith('.png') || url.endsWith('.jpg') || url.includes('google-analytics')) {
740
+ return route.abort();
741
+ }
742
+ route.continue();
743
+ });
744
+
745
+ const page = await context.newPage();
746
+ await page.setContent(html);
747
+ const buffer = await page.screenshot({ type: 'png' });
748
+ await browser.close();
749
+
750
+ res.set('Content-Type', 'image/png');
751
+ return res.send(buffer);
752
+ } catch (error) {
753
+ console.error('Error generating PNG:', error);
754
+ res.status(500).json({ error: 'Failed to convert HTML to PNG' });
755
+ }
756
  });
757
 
758
  app.get('/welcome', async (req, res) => {
 
1137
  </html>`;
1138
 
1139
  try {
1140
+ const browser = await chromium.launch({ headless: true }); // Launch Playwright Chromium browser
1141
+ const context = await browser.newContext({
1142
+ viewport: config.viewport,
1143
+ userAgent: config.userAgent
1144
+ });
1145
+
1146
+ await context.route('**/*', (route) => {
1147
+ const url = route.request().url();
1148
+ if (url.endsWith('.png') || url.endsWith('.jpg') || url.includes('google-analytics')) {
1149
+ return route.abort();
1150
+ }
1151
+ route.continue();
1152
+ });
1153
+
1154
+ const page = await context.newPage();
1155
  await page.setContent(html);
1156
  const buffer = await page.screenshot({ type: 'png' });
1157
  await browser.close();
 
1164
  }
1165
  });
1166
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1167
 
1168
  const PORT = process.env.PORT || 7860;
1169
 
1170
  app.listen(PORT, async () => {
1171
  console.log(`Server running on port ${PORT}`);
 
1172
  });
1173
 
1174
  process.on('SIGINT', async () => {
 
1175
  process.exit(0);
1176
  });